package cn.licoy.wdog.core.service.hospital.impl;

import cn.licoy.wdog.common.bean.ResponseCode;
import cn.licoy.wdog.common.exception.RequestException;
import cn.licoy.wdog.common.util.Encrypt;
import cn.licoy.wdog.common.util.Tools;
import cn.licoy.wdog.core.config.jwt.JwtToken;
import cn.licoy.wdog.core.dto.SignInDTO;
import cn.licoy.wdog.core.dto.hospitalUser.HospitalUserDto;
import cn.licoy.wdog.core.dto.hospitalUser.UpdateHouitalUserDto;
import cn.licoy.wdog.core.dto.hospitalUser.UpdatePasswordDto;
import cn.licoy.wdog.core.dto.system.user.UserAddDTO;
import cn.licoy.wdog.core.entity.hospital.DetectionInfo;
import cn.licoy.wdog.core.entity.hospital.HospitalRole;
import cn.licoy.wdog.core.entity.hospital.HospitalUser;
import cn.licoy.wdog.core.entity.hospital.Region;
import cn.licoy.wdog.core.entity.system.SysUser;
import cn.licoy.wdog.core.entity.system.SysUserRole;
import cn.licoy.wdog.core.mapper.hospital.HospitalMapper;
import cn.licoy.wdog.core.service.hospital.HospitalRoleService;
import cn.licoy.wdog.core.service.hospital.HospitalUserService;
import cn.licoy.wdog.core.service.hospital.SmscodeService;
import cn.licoy.wdog.core.service.system.SysRoleService;
import cn.licoy.wdog.core.service.system.SysUserRoleService;
import cn.licoy.wdog.core.vo.system.SysUserVO;
import com.baomidou.mybatisplus.mapper.EntityWrapper;
import com.baomidou.mybatisplus.plugins.Page;
import com.baomidou.mybatisplus.service.impl.ServiceImpl;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.DisabledAccountException;
import org.apache.shiro.subject.Subject;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import javax.servlet.http.HttpServletRequest;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

/**
 * @author Sunne
 * Create time 2018/6/21 15:53
 * @return null
 **/
@Service
@Transactional
public class HospitalUserServiceImpl extends ServiceImpl<HospitalMapper,HospitalUser> implements HospitalUserService {
    @Autowired
    private SysRoleService roleService;
    @Autowired
    private HospitalRoleService hospitalRoleService;
    @Autowired
    SmscodeService smscodeService;

    @Override
    public HospitalUser signIn(SignInDTO signInDTO) {
        if( "".equals(signInDTO.getUsername()) || "".equals(signInDTO.getPassword()) ){
            throw new RequestException(ResponseCode.SING_IN_INPUT_EMPTY);
        }
        JwtToken token = new JwtToken(null,signInDTO.getUsername(),signInDTO.getPassword());
        Subject subject = SecurityUtils.getSubject();
        try {
            subject.login(token);
            if(!subject.isAuthenticated()){
                throw new RequestException(ResponseCode.SIGN_IN_INPUT_FAIL);
            }
            HospitalUser user = this.selectOne(new EntityWrapper<HospitalUser>()
                    .eq("username",signInDTO.getUsername())
                    .eq("password",Encrypt.md5(String.valueOf(signInDTO.getPassword()+signInDTO.getUsername())))
            );
            return user;
        }catch (DisabledAccountException e){
            throw new RequestException(ResponseCode.SIGN_IN_INPUT_FAIL.code,e.getMessage(),e);
        }catch (Exception e){
            throw new RequestException(ResponseCode.SIGN_IN_FAIL,e);
        }
    }

    @Override
    public HospitalUser add(HospitalUserDto addDTO) {
        HospitalUser findUser = this.findUserByName(addDTO.getUsername(),false);

        if(findUser!=null){
            throw RequestException.fail(
                    String.format("已经存在用户名为 %s 的用户",addDTO.getUsername()));
        }
        findUser = new HospitalUser();
        BeanUtils.copyProperties(addDTO,findUser);
        findUser.setCreateDate(new Date());
        findUser.setStatus(1);
        findUser.setIsCertification("0");
        findUser.setIsCertification("0");
        findUser.setPassword(Encrypt.md5(String.valueOf(findUser.getPassword())+findUser.getUsername()));
        this.insert(findUser);
        JwtToken token = new JwtToken(null,addDTO.getUsername(),addDTO.getPassword());
        Subject subject = SecurityUtils.getSubject();
        try {
            subject.login(token);
            if(!subject.isAuthenticated()){
                throw new RequestException(ResponseCode.SIGN_IN_INPUT_FAIL);
            }
            HospitalUser user = this.selectOne(new EntityWrapper<HospitalUser>()
                    .eq("username",addDTO.getUsername())
                    .eq("password",Encrypt.md5(String.valueOf(addDTO.getPassword()+addDTO.getUsername())))
            );
            return user;
        }catch (DisabledAccountException e){
            throw new RequestException(ResponseCode.SIGN_IN_INPUT_FAIL.code,e.getMessage(),e);
        }catch (Exception e){
            throw new RequestException(ResponseCode.SIGN_IN_FAIL,e);
        }

    }

    @Override
    public HospitalUser findUserByName(String name, boolean hasResource) {
        HospitalUser hospitalUser = this.selectOne(new EntityWrapper<HospitalUser>().eq("username",name));
        if(hospitalUser == null){
            return null;
        }
        return hospitalUser;
    }

    @Override
    public void updatePassword(UpdatePasswordDto dto) {
        smscodeService.verificationCode(dto.getUsername(),dto.getCode(),"1");
        if ("".equals(dto.getPassword())||dto.getPassword()==null){
            throw new DisabledAccountException("密码码不能为空");
        }
        if ("".equals(dto.getUsername())||dto.getUsername()==null){
            throw new DisabledAccountException("用户不能为空");
        }
        HospitalUser hs = new HospitalUser();
        hs = this.selectOne(new EntityWrapper<HospitalUser>()
            .eq("username",dto.getUsername())
        );
        if (hs==null){
            throw RequestException.fail("用户不存在");
        }
        try {
            hs.setPassword(Encrypt.md5(String.valueOf(dto.getPassword()+dto.getUsername())));
            this.insertOrUpdate(hs);
        } catch (Exception e){
            throw new RequestException(ResponseCode.FAIL);
        }
    }

    @Override
    public void updateUserinfo(UpdateHouitalUserDto UpdateHouitalUserDto) {
        HttpServletRequest request =
                ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();
        boolean b = Tools.executeLogin(request);
        if(!b){
            throw RequestException.fail("身份已过期或无效，请重新认证");
        }
        Subject subject = SecurityUtils.getSubject();
        if(!subject.isAuthenticated()){
            throw new RequestException(ResponseCode.NOT_SING_IN);
        }
        JwtToken jwtToken = new JwtToken();
        Object principal = subject.getPrincipal();
        if(principal==null){
            throw RequestException.fail("用户信息获取失败");
        }
        BeanUtils.copyProperties(principal,jwtToken);
        HospitalUser user = this.findUserByName(jwtToken.getUsername(),false);
        if(user==null){
            throw RequestException.fail("用户不存在");
        }
        try {
            user.setProvince(UpdateHouitalUserDto.getProvince());
            user.setArea(UpdateHouitalUserDto.getArea());
            user.setCity(UpdateHouitalUserDto.getCity());
            user.setHospital(UpdateHouitalUserDto.getHospital());
            user.setDepartment(UpdateHouitalUserDto.getDepartment());
            user.setProfessionalNum(UpdateHouitalUserDto.getProfessionalNum());
            user.setIdcard(UpdateHouitalUserDto.getIdcard());
            user.setName(UpdateHouitalUserDto.getName());
            this.insertOrUpdate(user);
        }catch (Exception e){
            throw RequestException.fail("数据更新失败");
        }
    }

    @Override
    public HospitalUser findReginByUsername(String name) {
        HospitalUser user = this.selectOne(new EntityWrapper<HospitalUser>().eq("username",name));
        if(user == null){
            return null;
        }
        return user;
    }
    @Override
    public HospitalUser getCurrentUser(){
        HttpServletRequest request =
                ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();
        boolean b = Tools.executeLogin(request);
        if(!b){
            throw RequestException.fail("身份已过期或无效，请重新认证");
        }
        Subject subject = SecurityUtils.getSubject();
        if(!subject.isAuthenticated()){
            throw new RequestException(ResponseCode.NOT_SING_IN);
        }
        JwtToken jwtToken = new JwtToken();
        Object principal = subject.getPrincipal();
        if(principal==null){
            throw RequestException.fail("用户信息获取失败");
        }
        BeanUtils.copyProperties(principal,jwtToken);
        HospitalUser user = this.findUserByName(jwtToken.getUsername(),false);
        if(user==null){
            throw RequestException.fail("用户不存在");
        }
        return user;
    }
}
